<!DOCTYPE html>
<html>

<body>
  <!-- 绘制贝塞尔曲线-->
  <canvas id="c1" width="800" height="600">

  </canvas>
  <script>
    var p1 = document.getElementById("c1");
    var c1 = p1.getContext("2d");

    // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)  绘制三次贝塞尔曲线
    // 开始点为上一个点, 结束点为(x,y) 控制点为(cp1x, cp1y),(cp2x, cp2y)


    // quadraticCurveTo(cpx, cpy, x, y) 绘制二次贝塞尔曲线


    // 设置基本点对象
    var Point = function (x, y) {
      this.x = x;
      this.y = y;
    }

    // 定义控制点, 前2个为开始结束点, 后2个为控制点
    var cPt = [];
    function createControlPt(x, y) {
      if (cPt.length < 4) {
        cPt.push(new Point(x, y));
      }
    }

    // 控制绘制点
    function drawPt() {
      for (var i = 0; i < cPt.length; i++) {
        var c = "red";
        if (i < 2) {
          c = "green";
        }
        c1.strokeStyle = c;
        c1.strokeRect(cPt[i].x - 5, cPt[i].y - 5, 10, 10);
      }
    }

    // 判断一个点是否在一个以p2为中心的矩形中
    function isInRect(p1, p2, w, h) {
      return p1.x >= p2.x - w && p1.x <= p2.x + w && p1.y >= p2.y - h && p1.y <= p2.y + h;
    }

    // 判断一个点在哪一个控制区域中
    function getIdxCpt(p) {
      var idx = -1;
      for (var i = 0; i < cPt.length; i++) {
        if (isInRect(p, cPt[i], 5, 5)) {
          return i;
        }
      }
      return idx;
    }

    // 绘制控制点和起始点连线
    function drawBLine() {
      c1.strokeStyle = "gray";
      c1.beginPath();
      c1.moveTo(cPt[0].x, cPt[0].y);
      c1.lineTo(cPt[2].x, cPt[2].y);
      c1.stroke();
      c1.moveTo(cPt[1].x, cPt[1].y);
      c1.lineTo(cPt[3].x, cPt[3].y);
      c1.stroke;
    }

    // 绘制贝塞尔曲线
    function drawBei() {
      c1.beginPath();
      c1.strokeStyle = "red";
      c1.moveTo(cPt[0].x, cPt[0].y);
      c1.bezierCurveTo(cPt[2].x, cPt[2].y, cPt[3].x, cPt[3].y, cPt[1].x, cPt[1].y);
      c1.stroke();
    }

    // 绘制所有图形
    function draw() {
      drawPt();
      if (cPt.length > 3) {
        drawBLine();
        drawBei();
      }
    }

    // 设置鼠标点下和移动事件
    var selPt = new Point(-1, -1), sIdx;
    p1.onmousedown = function (e) {
      var x = e.offsetX, y = e.offsetY;
      selPt.x = x;
      selPt.y = y;
      createControlPt(x, y);
      draw();
      // 判断是否在控制点中
      if (cPt.length > 3) {
        sIdx = getIdxCpt(selPt);
        if (sIdx >= 0) {
          p1.onmousemove = function (e) {
            cPt[sIdx].x = e.offsetX;
            cPt[sIdx].y = e.offsetY;
            c1.clearRect(0, 0, 800, 600);
            draw();
          }
        }
      }
    }

    p1.onmouseUp = function () {
      this.onmousemove = null;
    }

  </script>
</body>

</html>